package com.logic.modular.game.battle.info.base;

import com.logic.modular.game.PvpCity;
import com.logic.modular.game.player.match.service.PvpCityServiceImpl;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * pvp玩家信息基础服务
 */
public class PvpPlayerInfoBaseServiceImpl {
    @Resource
    private RedisTemplate<Object, Object> redisTemplate;
    @Resource
    private HashOperations<Object, String, PvpPlayerInfo> hashOperations;
    @Resource
    private PvpCityServiceImpl pvpCityService;


    private final static String redisKey = "pvpMatch:%d:playerInfo";

    public void init(
            @NotNull PvpCity city
    ) {
        Long uid = city.getOwnerUid();
        Long matchId = city.getMatchId();

        Set<Long> currentCity = new HashSet<>();
        currentCity.add(city.getCoreCityId());

        Set<Long> alliesUidList = new HashSet<>();
        alliesUidList.add(uid);

        PvpPlayerInfo pvpPlayerInfo = new PvpPlayerInfo();
        pvpPlayerInfo.setPlayerId(uid);
        pvpPlayerInfo.setMatchId(matchId);
        pvpPlayerInfo.setAlliesUidList(alliesUidList);
        pvpPlayerInfo.setGrainRateCombined(city.getGrainRate());
        pvpPlayerInfo.setCopperRateCombined(city.getCopperRate());
        pvpPlayerInfo.setCurrentCity(currentCity);
        savaCache(pvpPlayerInfo);
    }

    public void savaCache(PvpPlayerInfo pvpPlayerInfo) {
        String key = String.format(redisKey, pvpPlayerInfo.getMatchId());
        hashOperations.put(key, pvpPlayerInfo.getPlayerId().toString(), pvpPlayerInfo);
        redisTemplate.expire(key, 1, TimeUnit.DAYS);
    }

    public List<PvpPlayerInfo> listCache(Long matchId) {
        String key = String.format(redisKey, matchId);
        return new ArrayList<>(hashOperations.entries(key).values());
    }

    public Map<String, PvpPlayerInfo> mapCache(Long matchId) {
        String key = String.format(redisKey, matchId);
        return hashOperations.entries(key);
    }

    public PvpPlayerInfo get(Long matchId, Long ownerUid) {
        String key1 = String.format(redisKey, matchId);
        return hashOperations.get(key1, ownerUid.toString());
    }

    public void update(PvpPlayerInfo pvpPlayerInfo) {
        String key1 = String.format(redisKey, pvpPlayerInfo.getMatchId());
        String key2 = pvpPlayerInfo.getPlayerId().toString();
        hashOperations.put(key1, key2, pvpPlayerInfo);
        redisTemplate.expire(key1, 1, TimeUnit.DAYS);
    }


    /**
     * 占领城池
     * 更新 原主人-城池信息|生存时间|生存排名|击杀者|
     * 当前-历史拥有城池数
     */
    public void playerOccupyTheCity(
            Long currentMatchId,
            Long ownerUid,
            Long coreCityId,
            Long winnerPlayerId
    ) {
        if (Objects.equals(winnerPlayerId, ownerUid)) {
            return;
        }

        boolean remove = false;
        if (ownerUid > 0) {
            PvpPlayerInfo source = get(currentMatchId, ownerUid);
            Set<Long> sourceCurrentCity = source.getCurrentCity();
            remove = sourceCurrentCity.remove(coreCityId);
            if (remove) {
                if (sourceCurrentCity.isEmpty()) {
                    source.obtainSurvivalTime();
                    source.setKilledBy(winnerPlayerId);
                    source.setIsDead(1);
                }
                savaCache(source);
            }
        }

        PvpPlayerInfo winner = get(currentMatchId, winnerPlayerId);
        Set<Long> currentCity = winner.getCurrentCity();
        currentCity.add(coreCityId);

        Integer maxCity = Math.max(winner.getMaxCity(), currentCity.size());
        winner.setMaxCity(maxCity);
        savaCache(winner);

        PvpCity pvpCity = pvpCityService.getPvpCity(coreCityId, currentMatchId);
        pvpCityService.clearProductivity(pvpCity);
        pvpCity.setOwnerUid(winnerPlayerId);
        pvpCityService.update(pvpCity);
    }
}
